/******************************************************************************
*
*   Copyright (c) 2020 Intel.
*
*   Licensed under the Apache License, Version 2.0 (the "License");
*   you may not use this file except in compliance with the License.
*   You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*   Unless required by applicable law or agreed to in writing, software
*   distributed under the License is distributed on an "AS IS" BASIS,
*   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*   See the License for the specific language governing permissions and
*   limitations under the License.
*
*******************************************************************************/

#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <sched.h>
#include <assert.h>
#include <err.h>
#include <libgen.h>
#include <sys/time.h>
#include <time.h>
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <pthread.h>
#include <sys/stat.h>
#include <unistd.h>
#include <getopt.h>  // for getopt


#include "common.h"
#include "config.h"
#include "xran_mlog_lnx.h"

#include "xran_fh_o_du.h"
#include "xran_compression.h"
#include "xran_cp_api.h"
#include "xran_sync_api.h"
#include "xran_mlog_task_id.h"

#define MAX_BBU_POOL_CORE_MASK  (4)


#define SW_FPGA_TOTAL_BUFFER_LEN 4*1024*1024*1024
#define SW_FPGA_SEGMENT_BUFFER_LEN 1*1024*1024*1024
#define SW_FPGA_FH_TOTAL_BUFFER_LEN 1*1024*1024*1024
#define FPGA_TO_SW_PRACH_RX_BUFFER_LEN   (8192)

#define NSEC_PER_SEC 1000000000

#define MAX_PKT_BURST (448+4) // 4x14x8
#define N_MAX_BUFFER_SEGMENT MAX_PKT_BURST

#define MAIN_PRIORITY 98
#define NUM_OF_SUBFRAME_PER_FRAME (10)

enum app_state state;

uint64_t  tick_per_usec;
static volatile uint64_t timer_last_irq_tick = 0;
static uint64_t tsc_resolution_hz = 0;

RuntimeConfig startupConfiguration = {0};

/* buffers size */
uint32_t    nFpgaToSW_FTH_RxBufferLen;
uint32_t    nFpgaToSW_PRACH_RxBufferLen;
uint32_t    nSW_ToFpga_FTH_TxBufferLen;

static struct xran_fh_init xranInit;
void * xranHandle = NULL;

struct sample_app_params {
    int num_vfs;
    char *cfg_file;
};


struct xran_fh_config  xranConf;
struct xran_fh_config  *pXranConf = NULL;

typedef struct
{
    uint32_t phaseFlag   :1;
    uint32_t NRARFCN     :22;
    uint32_t SULFreShift :1;
    uint32_t SULFlag     :1;
    uint32_t rsv         :7;
}FPGAPhaseCompCfg;

typedef struct XranLibConfig
{
    uint32_t nDriverCoreId;
    uint32_t nTimingAdvance;
    uint32_t nFhConfig;
    uint32_t nFhBufIntFlag;
    uint32_t nSectorNum;
    uint32_t nNrOfSlotInSf;
    uint32_t nNrofSfInFrame;
    void *   pFthInstanceHandles;
}XranLibConfigStruct;
typedef enum {
    XRANFTHTX_OUT = 0,
    XRANFTHTX_PRB_MAP_OUT,
    XRANFTHTX_SEC_DESC_OUT,
    XRANFTHRX_IN,
    XRANFTHRX_PRB_MAP_IN,
    XRANFTHTX_SEC_DESC_IN,
    XRANFTHRACH_IN,
    XRANSRS_IN,
    MAX_SW_XRAN_INTERFACE_NUM
}SWXRANInterfaceTypeEnum;

/*
 * manage one cell's all Ethernet frames for one DL or UL LTE subframe
 */
typedef struct {
    /* -1-this subframe is not used in current frame format
         0-this subframe can be transmitted, i.e., data is ready
          1-this subframe is waiting transmission, i.e., data is not ready
         10 - DL transmission missing deadline. When FE needs this subframe data but bValid is still 1,
        set bValid to 10.
    */
    int32_t bValid ; // when UL rx, it is subframe index.
    int32_t nSegToBeGen;
    int32_t nSegGenerated; // how many date segment are generated by DL LTE processing or received from FE
                       // -1 means that DL packet to be transmitted is not ready in BS
    int32_t nSegTransferred; // number of data segments has been transmitted or received
    struct rte_mbuf *pData[N_MAX_BUFFER_SEGMENT]; // point to DPDK allocated memory pool
    struct xran_buffer_list sBufferList;
} BbuIoBufCtrlStruct;

typedef struct  {
    uint64_t nCoreMask;
    int16_t cpuSocketId;
    uint8_t nDriverCoreId;
    uint8_t nFHCoreId;

    struct rte_mempool *bbuio_buf_pool;

    /* io struct */
    BbuIoBufCtrlStruct sFrontHaulTxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    BbuIoBufCtrlStruct sFrontHaulTxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    BbuIoBufCtrlStruct sFrontHaulRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    BbuIoBufCtrlStruct sFrontHaulRxPrbMapBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    BbuIoBufCtrlStruct sFHPrachRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];

    /* Cat B */
    BbuIoBufCtrlStruct sFHSrsRxBbuIoBufCtrl[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR];

    /* buffers lists */
    struct xran_flat_buffer sFrontHaulTxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
    struct xran_flat_buffer sFrontHaulTxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    struct xran_flat_buffer sFrontHaulRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];
    struct xran_flat_buffer sFrontHaulRxPrbMapBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR];
    struct xran_flat_buffer sFHPrachRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_NUM_OF_SYMBOL_PER_SLOT];

    /* Cat B SRS buffers */
    struct xran_flat_buffer sFHSrsRxBuffers[XRAN_N_FE_BUF_LEN][XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT];

    void*    nInstanceHandle[XRAN_PORTS_NUM][XRAN_MAX_SECTOR_NR]; // instance per sector
    uint32_t nBufPoolIndex[XRAN_MAX_SECTOR_NR][MAX_SW_XRAN_INTERFACE_NUM];   // every api owns unique buffer pool
    uint16_t nInstanceNum;

    uint64_t nTscTiming[XRAN_N_FE_BUF_LEN]; // records the TSC when a timing packet is received.
} BbuXranIoIfStruct;

static BbuXranIoIfStruct    gsXranIoIf;
static XranLibConfigStruct *gpXranLibConfig = NULL;

long old_rx_counter = 0;
long old_tx_counter = 0;


#define CPU_HZ tick_per_usec //us

/* Application User space functions */
void xran_fh_rx_callback(void *pCallbackTag, int32_t status);
void xran_fh_rx_prach_callback(void *pCallbackTag, int32_t status);

static BbuXranIoIfStruct *xran_get_ctx(void)
{
    return &gsXranIoIf;
}

static void print_menu()
{
    puts("+---------------------------------------+");
    puts("| Press 1 to start 5G NR XRAN traffic   |");
    puts("| Press 2 reserved for future use       |");
    puts("| Press 3 to quit                       |");
    puts("+---------------------------------------+");
}

static int32_t get_xran_sfidx(uint8_t nNrOfSlotInSf)
{
    int32_t nSfIdx = -1;
    uint32_t nFrameIdx;
    uint32_t nSubframeIdx;
    uint32_t nSlotIdx;
    uint64_t nSecond;

    uint32_t nXranTime  = xran_get_slot_idx(&nFrameIdx, &nSubframeIdx, &nSlotIdx, &nSecond);
    nSfIdx = nFrameIdx*NUM_OF_SUBFRAME_PER_FRAME*nNrOfSlotInSf
        + nSubframeIdx*nNrOfSlotInSf
        + nSlotIdx;
#if 0
    printf("\nxranTime is %d, return is %d, radio frame is %d, subframe is %d slot is %d tsc is %llu us",
        nXranTime,
        nSfIdx,
        nFrameIdx,
        nSubframeIdx,
        nSlotIdx,
        __rdtsc()/CPU_HZ);
#endif

    return nSfIdx;
}

void xran_fh_rx_callback(void *pCallbackTag, xran_status_t status)
{
    uint64_t t1 = MLogTick();
    uint32_t mlogVar[10];
    uint32_t mlogVarCnt = 0;
    uint8_t Numerlogy = xranConf.frame_conf.nNumerology;
    uint8_t nNrOfSlotInSf = 1<<Numerlogy;
    int32_t sfIdx = get_xran_sfidx(nNrOfSlotInSf);

    mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
    mlogVar[mlogVarCnt++] = status >> 16; /* tti */
    mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
    mlogVar[mlogVarCnt++] = (uint32_t)sfIdx;
    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
    rte_pause();

    MLogTask(PID_GNB_SYM_CB, t1, MLogTick());
    return;
}

void xran_fh_rx_prach_callback(void *pCallbackTag, xran_status_t status)
{
    uint64_t t1 = MLogTick();
    uint32_t mlogVar[10];
    uint32_t mlogVarCnt = 0;

    mlogVar[mlogVarCnt++] = 0xDDDDDDDD;
    mlogVar[mlogVarCnt++] = status >> 16; /* tti */
    mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
    rte_pause();

    MLogTask(PID_GNB_PRACH_CB, t1, MLogTick());
}

void xran_fh_rx_srs_callback(void *pCallbackTag, xran_status_t status)
{
    uint64_t t1 = MLogTick();
    uint32_t mlogVar[10];
    uint32_t mlogVarCnt = 0;

    mlogVar[mlogVarCnt++] = 0xCCCCCCCC;
    mlogVar[mlogVarCnt++] = status >> 16; /* tti */
    mlogVar[mlogVarCnt++] = status & 0xFF; /* sym */
    MLogAddVariables(mlogVarCnt, mlogVar, MLogTick());
    rte_pause();

    MLogTask(PID_GNB_SRS_CB, t1, MLogTick());
}


//-------------------------------------------------------------------------------------------
/** @ingroup group_nbiot_source_auxlib_timer
 *
 *  @param   void
 *
 *  @return  Ticks
 *
 *  @description
 *  This function reads the rtdsc clock and returns the current value in there.
 *
**/
//-------------------------------------------------------------------------------------------
unsigned long timer_get_ticks(void)
{
    unsigned long ret;
    union
    {
        unsigned long tsc_64;
        struct
        {
            uint32_t lo_32;
            uint32_t hi_32;
        };
    } tsc;

    __asm volatile("rdtsc" :
             "=a" (tsc.lo_32),
             "=d" (tsc.hi_32));

     ret = ((unsigned long)tsc.tsc_64);
     return ret;
}

//-------------------------------------------------------------------------------------------
/** @ingroup group_lte_source_auxlib_timer
 *
 *  @param   void
 *
 *  @return  0 if SUCCESS
 *
 *  @description
 *  This function gets the clock speed of the core and figures out number of ticks per usec.
 *  It is used by l1app and testmac applications to initialize the mlog utility
 *
**/
//-------------------------------------------------------------------------------------------
int timer_set_tsc_freq_from_clock(void)
{
#define NS_PER_SEC 1E9
    struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
    struct timespec t_start, t_end;
    uint64_t tsc_resolution_hz = 0;

    if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
    {
        unsigned long ns, end, start = timer_get_ticks();
        nanosleep(&sleeptime,NULL);
        clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
        end = timer_get_ticks();
        ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC);
        ns += (t_end.tv_nsec - t_start.tv_nsec);

        double secs = (double)ns/NS_PER_SEC;
        tsc_resolution_hz = (unsigned long)((end - start)/secs);

        tick_per_usec = (tsc_resolution_hz / 1000000);
        printf("System clock (rdtsc) resolution %lu [Hz]\n", tsc_resolution_hz);
        printf("Ticks per us %lu\n", tick_per_usec);
        return 0;
    }

    return -1;
}

int physide_dl_tti_call_back(void * param)
{
    uint64_t t1 = MLogTick();
    rte_pause();
    MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
    return 0;
}

int physide_ul_half_slot_call_back(void * param)
{
    uint64_t t1 = MLogTick();
    rte_pause();
    MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
    return 0;
}

int physide_ul_full_slot_call_back(void * param)
{
    uint64_t t1 = MLogTick();
    rte_pause();
    MLogTask(PID_GNB_PROC_TIMING, t1, MLogTick());
    return 0;
}

int32_t init_xran(void)
{
    BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
    xran_status_t status;
    int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
    int32_t nSectorNum;
    int32_t i, j, k, z;

    void *ptr;
    void *mb;
    uint32_t *u32dptr;
    uint16_t *u16dptr;
    uint8_t  *u8dptr;
    uint32_t xran_max_antenna_nr = RTE_MAX(startupConfiguration.numAxc, startupConfiguration.numUlAxc);
    uint32_t xran_max_ant_array_elm_nr = RTE_MAX(startupConfiguration.antElmTRx, xran_max_antenna_nr);

    SWXRANInterfaceTypeEnum eInterfaceType;

    XranLibConfigStruct  *ptrLibConfig;

    struct xran_buffer_list *pFthTxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
    struct xran_buffer_list *pFthTxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
    struct xran_buffer_list *pFthRxBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
    struct xran_buffer_list *pFthRxPrbMapBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
    struct xran_buffer_list *pFthRxRachBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANTENNA_NR][XRAN_N_FE_BUF_LEN];
    struct xran_buffer_list *pFthRxSrsBuffer[XRAN_MAX_SECTOR_NR][XRAN_MAX_ANT_ARRAY_ELM_NR][XRAN_N_FE_BUF_LEN];

    for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
    {
        nSectorIndex[nSectorNum] = nSectorNum;
    }

    nSectorNum = numCCPorts;
    printf ("XRAN front haul xran_mm_init \n");
    status = xran_mm_init (xranHandle, (uint64_t) SW_FPGA_FH_TOTAL_BUFFER_LEN, SW_FPGA_SEGMENT_BUFFER_LEN);
    if (status != XRAN_STATUS_SUCCESS)
    {
        printf ("Failed at XRAN front haul xran_mm_init \n");
        exit(-1);
    }

    psBbuIo->nInstanceNum = numCCPorts;

    for (k = 0; k < XRAN_PORTS_NUM; k++) {
        status = xran_sector_get_instances (xranHandle, psBbuIo->nInstanceNum,&psBbuIo->nInstanceHandle[k][0]);
        if (status != XRAN_STATUS_SUCCESS)
        {
            printf ("get sector instance failed %d for XRAN nInstanceNum %d\n",k, psBbuIo->nInstanceNum);
            exit(-1);
        }
        for (i = 0; i < psBbuIo->nInstanceNum; i++){
            printf("%s [%d]: CC %d handle %p\n", __FUNCTION__, k, i, psBbuIo->nInstanceHandle[0][i]);
        }
    }

    printf("Sucess xran_mm_init \n");
    gpXranLibConfig = (XranLibConfigStruct*)malloc(sizeof(XranLibConfigStruct));
    ptrLibConfig = gpXranLibConfig;
    if (ptrLibConfig)
    {
    #if 0
        ptrLibConfig->nDriverCoreId =  psBbuIo->nDriverCoreId;
        ptrLibConfig->pFecInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FEC][0]);
        ptrLibConfig->pFthInstanceHandles = &(psBbuIo->nInstanceHandle[FPGA_FRONTHAUL][0]);
        ptrLibConfig->nTimingAdvance = psFPGAInitPara->nTimeAdvance;
        ptrLibConfig->nFhConfig = psFPGAInitPara->nEthPorts;
        ptrLibConfig->nFhBufIntFlag = 0; //need init fronthaul buffer, then set to 1.
        ptrLibConfig->nNrofSfInFrame = NUM_OF_SUBFRAME_PER_FRAME;
        ptrLibConfig->nNrOfSlotInSf = pConfigParams->nNumOfSlotPerSubframe;
        if (pConfigParams->nNumerology < 3)
        {
            ptrLibConfig->nSectorNum = psFPGAInitPara->nSecNum;
        }
    #endif
    }
    else
    {
        printf ("could not allocate ptrLibConfig in init_xran\n");
        exit(-1);
    }

    printf("nSectorNum %d\n", nSectorNum);

    /* Init Memory */
    for(i = 0; i<nSectorNum; i++)
    {
        eInterfaceType = XRANFTHTX_OUT;
        printf("nSectorIndex[%d] = %d\n",i,  nSectorIndex[i]);
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
            XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at  xran_bm_init , status %d\n", status);
        }
        for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_antenna_nr; z++){
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
                psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxBuffers[j][i][z][0];

                for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
                {
                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen; // 14 symbols 3200bytes/symbol
                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status){
                        rte_panic("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                    }
                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
                    psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;

                    if(ptr){
                        u32dptr = (uint32_t*)(ptr);
                        memset(u32dptr, 0x0, nSW_ToFpga_FTH_TxBufferLen);
                       // ptr_temp[0] = j; // TTI
                       // ptr_temp[1] = i; // Sec
                       // ptr_temp[2] = z; // Ant
                       // ptr_temp[3] = k; // sym
                    }
                }
            }
        }

        /* C-plane DL */
        eInterfaceType = XRANFTHTX_SEC_DESC_OUT;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
            XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at  xran_bm_init , status %d\n", status);
        }

        eInterfaceType = XRANFTHTX_PRB_MAP_OUT;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
            XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at  xran_bm_init , status %d\n", status);
        }

        for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_antenna_nr; z++){
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
                psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulTxPrbMapBuffers[j][i][z];

                {
                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status) {
                        rte_panic("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                    }
                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
                    psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;

                    if(ptr){
                        void *sd_ptr;
                        void *sd_mb;
                        int elm_id;
                        struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;
                        if (startupConfiguration.appMode == APP_O_DU)
                            memcpy(ptr, &startupConfiguration.PrbMapDl, sizeof(struct xran_prb_map));
                        else
                            memcpy(ptr, &startupConfiguration.PrbMapUl, sizeof(struct xran_prb_map));

                        for (elm_id = 0; elm_id < p_rb_map->nPrbElm; elm_id++){
                            struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
                            for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
                                status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][XRANFTHTX_SEC_DESC_OUT],&sd_ptr, &sd_mb);
                                if(XRAN_STATUS_SUCCESS != status){
                                    rte_panic("SD Failed at  xran_bm_allocate_buffer , status %d\n",status);
                                }
                                pPrbElem->p_sec_desc[k] = sd_ptr;
                                memset(sd_ptr,0,sizeof(struct xran_section_desc));
                            }
                        }
                    }
                }
            }
        }
    }

    for(i = 0; i<nSectorNum; i++)
    {
        eInterfaceType = XRANFTHRX_IN;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType], XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);
        if(XRAN_STATUS_SUCCESS != status)
        {
            printf("Failed at xran_bm_init, status %d\n", status);
            iAssert(status == XRAN_STATUS_SUCCESS);
        }

        for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_antenna_nr; z++){
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
                psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxBuffers[j][i][z][0];
                for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
                {
                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nFpgaToSW_FTH_RxBufferLen; // 1 symbols 3200bytes
                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status) {
                        rte_panic("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                    }
                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
                    psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *) mb;
                    if(ptr){
                        u32dptr = (uint32_t*)(ptr);
                        uint8_t *ptr_temp = (uint8_t *)ptr;
                        memset(u32dptr, 0x0, nFpgaToSW_FTH_RxBufferLen);
                     //   ptr_temp[0] = j; // TTI
                     //   ptr_temp[1] = i; // Sec
                     //   ptr_temp[2] = z; // Ant
                     //   ptr_temp[3] = k; // sym
                    }
                }
            }
        }

        /* C-plane */
        eInterfaceType = XRANFTHTX_SEC_DESC_IN;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
            XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT*XRAN_MAX_SECTIONS_PER_SYM, sizeof(struct xran_section_desc));
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at  xran_bm_init , status %d\n", status);
        }
        eInterfaceType = XRANFTHRX_PRB_MAP_IN;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i], &psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
                XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT, sizeof(struct xran_prb_map));
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at xran_bm_init, status %d\n", status);
        }

        for(j = 0;j < XRAN_N_FE_BUF_LEN; j++) {
            for(z = 0; z < xran_max_antenna_nr; z++){
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = XRAN_NUM_OF_SYMBOL_PER_SLOT;
                psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFrontHaulRxPrbMapBuffers[j][i][z];
                {
                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nElementLenInBytes = sizeof(struct xran_prb_map);
                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nNumberOfElements = 1;
                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status) {
                        rte_panic("Failed at  xran_bm_allocate_buffer , status %d\n",status);
                    }
                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pData = (uint8_t *)ptr;
                    psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList.pBuffers->pCtrl = (void *)mb;
                    if(ptr){
                        void *sd_ptr;
                        void *sd_mb;
                        int elm_id;
                        struct xran_prb_map * p_rb_map = (struct xran_prb_map *)ptr;

                        if (startupConfiguration.appMode == APP_O_DU)
                            memcpy(ptr, &startupConfiguration.PrbMapUl, sizeof(struct xran_prb_map));
                        else
                            memcpy(ptr, &startupConfiguration.PrbMapDl, sizeof(struct xran_prb_map));

                        for (elm_id = 0; elm_id < p_rb_map->nPrbElm; elm_id++){
                            struct xran_prb_elm *pPrbElem = &p_rb_map->prbMap[elm_id];
                            for(k = 0; k < XRAN_NUM_OF_SYMBOL_PER_SLOT; k++){
                                status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i], psBbuIo->nBufPoolIndex[nSectorIndex[i]][XRANFTHTX_SEC_DESC_IN],&sd_ptr, &sd_mb);
                                if(XRAN_STATUS_SUCCESS != status){
                                    rte_panic("SD Failed at  xran_bm_allocate_buffer , status %d\n",status);
                                }
                                pPrbElem->p_sec_desc[k] = sd_ptr;
                                memset(sd_ptr,0,sizeof(struct xran_section_desc));
                            }
                        }
                    }
                }
            }
        }
    }


    // add prach rx buffer
    for(i = 0; i<nSectorNum; i++)
    {
        eInterfaceType = XRANFTHRACH_IN;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],XRAN_N_FE_BUF_LEN*xran_max_antenna_nr*XRAN_NUM_OF_SYMBOL_PER_SLOT, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at xran_bm_init, status %d\n", status);
        }
        for(j = 0;j < XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_antenna_nr; z++){
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = xran_max_antenna_nr; // ant number.
                psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHPrachRxBuffers[j][i][z][0];
                for(k = 0; k< XRAN_NUM_OF_SYMBOL_PER_SLOT; k++)
                {
                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = FPGA_TO_SW_PRACH_RX_BUFFER_LEN;
                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status) {
                        rte_panic("Failed at  xran_bm_allocate_buffer, status %d\n",status);
                    }
                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
                    psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
                    if(ptr){
                        u32dptr = (uint32_t*)(ptr);
                        memset(u32dptr, 0x0, FPGA_TO_SW_PRACH_RX_BUFFER_LEN);
                    }
                }
            }
        }
    }

    /* add SRS rx buffer */
    for(i = 0; i<nSectorNum && xran_max_ant_array_elm_nr; i++)
    {
        eInterfaceType = XRANSRS_IN;
        status = xran_bm_init(psBbuIo->nInstanceHandle[0][i],&psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],
            XRAN_N_FE_BUF_LEN*xran_max_ant_array_elm_nr*XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT, nSW_ToFpga_FTH_TxBufferLen);

        if(XRAN_STATUS_SUCCESS != status) {
            rte_panic("Failed at xran_bm_init, status %d\n", status);
        }
        for(j = 0; j < XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_ant_array_elm_nr; z++){
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].bValid = 0;
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegGenerated = -1;
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegToBeGen = -1;
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].nSegTransferred = 0;
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.nNumBuffers = xran_max_ant_array_elm_nr; /* ant number */
                psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers = &psBbuIo->sFHSrsRxBuffers[j][i][z][0];
                for(k = 0; k < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; k++)
                {
                    psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nElementLenInBytes = nSW_ToFpga_FTH_TxBufferLen;
                    psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nNumberOfElements = 1;
                    psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].nOffsetInBytes = 0;
                    status = xran_bm_allocate_buffer(psBbuIo->nInstanceHandle[0][i],psBbuIo->nBufPoolIndex[nSectorIndex[i]][eInterfaceType],&ptr, &mb);
                    if(XRAN_STATUS_SUCCESS != status) {
                        rte_panic("Failed at  xran_bm_allocate_buffer, status %d\n",status);
                    }
                    psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pData = (uint8_t *)ptr;
                    psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList.pBuffers[k].pCtrl = (void *)mb;
                    if(ptr){
                        u32dptr = (uint32_t*)(ptr);
                        memset(u32dptr, 0x0, nSW_ToFpga_FTH_TxBufferLen);
                    }
                }
            }
        }
    }

    for(i=0; i<nSectorNum; i++)
    {
        for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < XRAN_MAX_ANTENNA_NR; z++){
                pFthTxBuffer[i][z][j]       = NULL;
                pFthTxPrbMapBuffer[i][z][j] = NULL;
                pFthRxBuffer[i][z][j]       = NULL;
                pFthRxPrbMapBuffer[i][z][j] = NULL;
                pFthRxRachBuffer[i][z][j]   = NULL;
            }
            for(z = 0; z < XRAN_MAX_ANT_ARRAY_ELM_NR; z++){
                pFthRxSrsBuffer[i][z][j] = NULL;
            }
        }
    }

    for(i=0; i<nSectorNum; i++)
    {
        for(j=0; j<XRAN_N_FE_BUF_LEN; j++)
        {
            for(z = 0; z < xran_max_antenna_nr; z++){
                pFthTxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxBbuIoBufCtrl[j][i][z].sBufferList);
                pFthTxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
                pFthRxBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxBbuIoBufCtrl[j][i][z].sBufferList);
                pFthRxPrbMapBuffer[i][z][j]     = &(psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[j][i][z].sBufferList);
                pFthRxRachBuffer[i][z][j] = &(psBbuIo->sFHPrachRxBbuIoBufCtrl[j][i][z].sBufferList);
            }

            for(z = 0; z < xran_max_ant_array_elm_nr && xran_max_ant_array_elm_nr; z++){
                pFthRxSrsBuffer[i][z][j] = &(psBbuIo->sFHSrsRxBbuIoBufCtrl[j][i][z].sBufferList);
            }
        }
    }

    if(NULL != psBbuIo->nInstanceHandle[0])
    {
        /* add pusch callback */
        for (i = 0; i<nSectorNum; i++)
        {
            xran_5g_fronthault_config (psBbuIo->nInstanceHandle[0][i],
                pFthTxBuffer[i],
                pFthTxPrbMapBuffer[i],
                pFthRxBuffer[i],
                pFthRxPrbMapBuffer[i],
                xran_fh_rx_callback,  &pFthRxBuffer[i][0]);
        }

        /* add prach callback here */
        for (i = 0; i<nSectorNum; i++)
        {
            xran_5g_prach_req(psBbuIo->nInstanceHandle[0][i], pFthRxRachBuffer[i],
                xran_fh_rx_prach_callback,&pFthRxRachBuffer[i][0]);
        }

        /* add SRS callback here */
        for (i = 0; i<nSectorNum && xran_max_ant_array_elm_nr; i++) {
            xran_5g_srs_req(psBbuIo->nInstanceHandle[0][i], pFthRxSrsBuffer[i],
                xran_fh_rx_srs_callback,&pFthRxSrsBuffer[i][0]);
        }

        ptrLibConfig->nFhBufIntFlag = 1;
    }

    return status;
}

int init_xran_iq_content(void)
{
    BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
    xran_status_t status;
    int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
    int32_t nSectorNum;
    int32_t cc_id, ant_id, sym_id, tti;
    int32_t flowId;

    uint8_t    frame_id    = 0;
    uint8_t    subframe_id = 0;
    uint8_t    slot_id     = 0;
    uint8_t    sym         = 0;

    void *ptr;
    uint32_t *u32dptr;
    uint16_t *u16dptr;
    uint8_t  *u8dptr;

    uint32_t xran_max_antenna_nr = RTE_MAX(startupConfiguration.numAxc, startupConfiguration.numUlAxc);
    uint32_t xran_max_ant_array_elm_nr = RTE_MAX(startupConfiguration.antElmTRx, xran_max_antenna_nr);

    char *pos = NULL;
    struct xran_prb_map *pRbMap = NULL;

    for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
    {
        nSectorIndex[nSectorNum] = nSectorNum;
    }
    nSectorNum = numCCPorts;
    printf ("init_xran_iq_content\n");

    /* Init Memory */
    for(cc_id = 0; cc_id <nSectorNum; cc_id++)
    {
        for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti ++) {
            for(ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++){
                for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {

                    if(startupConfiguration.appMode == APP_O_DU)
                        flowId = startupConfiguration.numAxc * cc_id + ant_id;
                    else
                        flowId = startupConfiguration.numUlAxc * cc_id + ant_id;

                    if(p_tx_play_buffer[flowId]){
                        /* c-plane DL */
                        pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulTxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
                        if(pRbMap){
                            if (xranInit.DynamicSectionEna == 0){
                                pRbMap->dir = XRAN_DIR_DL;
                                pRbMap->xran_port = 0;
                                pRbMap->band_id = 0;
                                pRbMap->cc_id = cc_id;
                                pRbMap->ru_port_id = ant_id;
                                pRbMap->tti_id = tti;
                                pRbMap->start_sym_id = 0;
                                pRbMap->nPrbElm = 1;
                                pRbMap->prbMap[0].nStartSymb = 0;
                                pRbMap->prbMap[0].numSymb = 14;
                                pRbMap->prbMap[0].nRBStart = 0;
                                pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
                                pRbMap->prbMap[0].nBeamIndex = 0;
                                pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
                                pRbMap->prbMap[0].iqWidth    = 16;
                            } else if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B
                                      && startupConfiguration.appMode == APP_O_DU
                                      && sym_id == 0){ /* BF Ws are per slot */
                                int idxElm = 0;
                                char* dl_bfw_pos  = ((char*)p_tx_dl_bfw_buffer[flowId]) + tx_dl_bfw_buffer_position[flowId];
                                struct xran_prb_elm* p_pRbMapElm = NULL;
                                for (idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
                                    p_pRbMapElm = &pRbMap->prbMap[idxElm];
                                    p_pRbMapElm->bf_weight.nAntElmTRx = pXranConf->nAntElmTRx;
                                    if(p_pRbMapElm->BeamFormingType == XRAN_BEAM_WEIGHT && p_pRbMapElm->bf_weight_update){
                                        int16_t  ext_len       = 9600;
                                        int16_t  ext_sec_total = 0;
                                        int8_t * ext_buf =(int8_t*) xran_malloc(ext_len);
                                        int8_t * ext_buf_start = ext_buf;
                                        if (ext_buf){
                                            ext_buf += (RTE_PKTMBUF_HEADROOM +
                                                       sizeof (struct xran_ecpri_hdr) +
                                                       sizeof(struct xran_cp_radioapp_common_header) +
                                                       sizeof(struct xran_cp_radioapp_section1));

                                            ext_len -= (RTE_PKTMBUF_HEADROOM +
                                                        sizeof(struct xran_ecpri_hdr) +
                                                        sizeof(struct xran_cp_radioapp_common_header) +
                                                        sizeof(struct xran_cp_radioapp_section1));

                                            ext_sec_total =  xran_cp_populate_section_ext_1((int8_t *)ext_buf,
                                                                      ext_len,
                                                                      (int16_t *) (dl_bfw_pos + (p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4),
                                                                      p_pRbMapElm->nRBSize,
                                                                      pXranConf->nAntElmTRx,
                                                                      p_pRbMapElm->iqWidth, p_pRbMapElm->compMethod);
                                            if(ext_sec_total > 0){
                                                p_pRbMapElm->bf_weight.p_ext_start    = ext_buf_start;
                                                p_pRbMapElm->bf_weight.p_ext_section  = ext_buf;
                                                p_pRbMapElm->bf_weight.ext_section_sz = ext_sec_total;
                                            }else {
                                                rte_panic("xran_cp_populate_section_ext_1 return error [%d]\n", ext_sec_total);
                                            }
                                        } else {
                                            rte_panic("xran_malloc return NULL\n");
                                        }
                                    }
                                }
                            }
                        } else {
                            printf("DL pRbMap ==NULL\n");
                            exit(-1);
                        }

                        pos =  ((char*)p_tx_play_buffer[flowId]) + tx_play_buffer_position[flowId];
                        ptr = psBbuIo->sFrontHaulTxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;

                        if(ptr && pos){
                            int idxElm = 0;
                            u8dptr = (uint8_t*)ptr;
                            int16_t payload_len = 0;

                            uint8_t  *dst = (uint8_t *)u8dptr;
                            uint8_t  *src = (uint8_t *)pos;
                            struct xran_prb_elm* p_prbMapElm = &pRbMap->prbMap[idxElm];
                            dst =  xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
                            for (idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++) {
                                struct xran_section_desc *p_sec_desc = NULL;
                                p_prbMapElm = &pRbMap->prbMap[idxElm];
                                p_sec_desc =  p_prbMapElm->p_sec_desc[sym_id];

                                if(p_sec_desc == NULL){
                                    printf ("p_sec_desc == NULL\n");
                                    exit(-1);
                                }
                                src = (uint8_t *)(pos + p_prbMapElm->nRBStart*N_SC_PER_PRB*4L);

                                if(p_prbMapElm->compMethod == XRAN_COMPMETHOD_NONE) {
                                    payload_len = p_prbMapElm->nRBSize*N_SC_PER_PRB*4L;
                                    rte_memcpy(dst, src, payload_len);

                                } else if (p_prbMapElm->compMethod == XRAN_COMPMETHOD_BLKFLOAT) {
                                    struct xranlib_compress_request  bfp_com_req;
                                    struct xranlib_compress_response bfp_com_rsp;

                                    memset(&bfp_com_req, 0, sizeof(struct xranlib_compress_request));
                                    memset(&bfp_com_rsp, 0, sizeof(struct xranlib_compress_response));

                                    bfp_com_req.data_in    = (int16_t*)src;
                                    bfp_com_req.numRBs     = p_prbMapElm->nRBSize;
                                    bfp_com_req.len        = p_prbMapElm->nRBSize*N_SC_PER_PRB*4L;
                                    bfp_com_req.compMethod = p_prbMapElm->compMethod;
                                    bfp_com_req.iqWidth    = p_prbMapElm->iqWidth;

                                    bfp_com_rsp.data_out   = (int8_t*)dst;
                                    bfp_com_rsp.len        = 0;

                                    xranlib_compress_avx512(&bfp_com_req, &bfp_com_rsp);
                                    payload_len = bfp_com_rsp.len;

                                }else {
                                    printf ("p_prbMapElm->compMethod == %d is not supported\n",
                                        p_prbMapElm->compMethod);
                                    exit(-1);
                                }

                                /* update RB map for given element */
                                p_sec_desc->iq_buffer_offset = RTE_PTR_DIFF(dst, u8dptr);
                                p_sec_desc->iq_buffer_len = payload_len;

                                /* add headroom for ORAN headers between IQs for chunk of RBs*/
                                dst += payload_len;
                                dst  = xran_add_hdr_offset(dst, p_prbMapElm->compMethod);
                            }
                        } else {
                            exit(-1);
                            printf("ptr ==NULL\n");
                        }


                        /* c-plane UL */
                        pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
                        if(pRbMap){
                            if (xranInit.DynamicSectionEna == 0){
                                pRbMap->dir = XRAN_DIR_UL;
                                pRbMap->xran_port = 0;
                                pRbMap->band_id = 0;
                                pRbMap->cc_id = cc_id;
                                pRbMap->ru_port_id = ant_id;
                                pRbMap->tti_id = tti;
                                pRbMap->start_sym_id = 0;
                                pRbMap->nPrbElm = 1;
                                pRbMap->prbMap[0].nRBStart = 0;
                                pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
                                pRbMap->prbMap[0].nStartSymb = 0;
                                pRbMap->prbMap[0].numSymb = 14;
                                pRbMap->prbMap[0].p_sec_desc[sym_id]->iq_buffer_offset = 0;
                                pRbMap->prbMap[0].p_sec_desc[sym_id]->iq_buffer_len    = pXranConf->nULRBs *4L;
                                pRbMap->prbMap[0].nBeamIndex = 0;
                                pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
                            } else if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B
                                      && startupConfiguration.appMode == APP_O_DU
                                      && sym_id == 0){
                                int idxElm = 0;
                                char        * ul_bfw_pos =  ((char*)p_tx_ul_bfw_buffer[flowId]) + tx_ul_bfw_buffer_position[flowId];
                                struct xran_prb_elm* p_pRbMapElm = NULL;

                                for (idxElm = 0;  idxElm < pRbMap->nPrbElm; idxElm++){
                                    p_pRbMapElm = &pRbMap->prbMap[idxElm];
                                    p_pRbMapElm->bf_weight.nAntElmTRx = pXranConf->nAntElmTRx;
                                    if(p_pRbMapElm->BeamFormingType == XRAN_BEAM_WEIGHT && p_pRbMapElm->bf_weight_update){
                                        int16_t  ext_len       = 9600;
                                        int16_t  ext_sec_total = 0;
                                        int8_t * ext_buf =(int8_t*) xran_malloc(ext_len);
                                        int8_t * ext_buf_start = ext_buf;
                                        int idRb = 0;
                                        int16_t *ptr = NULL;
                                        int i;
                                        if (ext_buf){

                                            ext_buf += (RTE_PKTMBUF_HEADROOM +
                                                       sizeof(struct xran_ecpri_hdr) +
                                                       sizeof(struct xran_cp_radioapp_section1_header) +
                                                       sizeof(struct xran_cp_radioapp_section1));

                                            ext_len -= (RTE_PKTMBUF_HEADROOM +
                                                        sizeof(struct xran_ecpri_hdr) +
                                                        sizeof(struct xran_cp_radioapp_section1_header) +
                                                        sizeof(struct xran_cp_radioapp_section1));

                                            ptr = (int16_t*)(ul_bfw_pos +(p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4);
                                            ext_sec_total =  xran_cp_populate_section_ext_1((int8_t *)ext_buf,
                                                                      ext_len,
                                                                      (int16_t *) (ul_bfw_pos + (p_pRbMapElm->nRBStart*pXranConf->nAntElmTRx)*4),
                                                                      p_pRbMapElm->nRBSize,
                                                                      pXranConf->nAntElmTRx,
                                                                      p_pRbMapElm->iqWidth, p_pRbMapElm->compMethod);
                                            if(ext_sec_total > 0){
                                                p_pRbMapElm->bf_weight.p_ext_start    = ext_buf_start;
                                                p_pRbMapElm->bf_weight.p_ext_section  = ext_buf;
                                                p_pRbMapElm->bf_weight.ext_section_sz = ext_sec_total;
                                            }else {
                                                rte_panic("xran_cp_populate_section_ext_1 return error [%d]\n", ext_sec_total);
                                            }
                                        } else {
                                            rte_panic("xran_malloc return NULL\n");
                                        }
                                    }
                                }
                            }
                        } else {
                            printf("DL pRbMap ==NULL\n");
                            exit(-1);
                        }

                        tx_play_buffer_position[flowId] += pXranConf->nDLRBs*N_SC_PER_PRB*4;

                        if(tx_play_buffer_position[flowId] >= tx_play_buffer_size[flowId])
                            tx_play_buffer_position[flowId] = 0;

                        if(pXranConf->ru_conf.xranCat == XRAN_CATEGORY_B
                           && startupConfiguration.appMode == APP_O_DU
                           && sym_id == 0) {
                            tx_dl_bfw_buffer_position[flowId] += (pXranConf->nDLRBs*pXranConf->nAntElmTRx)*4;
                            if(tx_dl_bfw_buffer_position[flowId] >= tx_dl_bfw_buffer_size[flowId])
                                tx_dl_bfw_buffer_position[flowId] = 0;

                            tx_ul_bfw_buffer_position[flowId] += (pXranConf->nULRBs*pXranConf->nAntElmTRx)*4;
                            if(tx_ul_bfw_buffer_position[flowId] >= tx_ul_bfw_buffer_size[flowId])
                                tx_ul_bfw_buffer_position[flowId] = 0;
                        }
                    } else {
                        //printf("flowId %d\n", flowId);
                    }
                }
            }

            /* prach TX for RU only */
            if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
                for(ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++){
                    for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
                        flowId = startupConfiguration.numAxc*cc_id + ant_id;

                        if(p_tx_prach_play_buffer[flowId]){
                            pos =  ((char*)p_tx_prach_play_buffer[flowId]);

                            ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;

                            if(ptr && pos){
                                u32dptr = (uint32_t*)(ptr);
                                /* duplicate full PRACH (repetition * occassions ) in every symbol */
                                memset(u32dptr,0 , PRACH_PLAYBACK_BUFFER_BYTES);
                                rte_memcpy(u32dptr, pos, RTE_MIN(PRACH_PLAYBACK_BUFFER_BYTES, tx_prach_play_buffer_size[flowId]));
                            } else {
                                exit(-1);
                                printf("ptr ==NULL\n");
                            }
                        } else {
                            //printf("flowId %d\n", flowId);
                        }
                    }
                }
            }

            /* SRS TX for RU only */
            if(startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){
                for(ant_id = 0; ant_id < xran_max_ant_array_elm_nr; ant_id++){
                    for(sym_id = 0; sym_id < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; sym_id++) {
                        flowId = startupConfiguration.antElmTRx*cc_id + ant_id;

                        if(p_tx_srs_play_buffer[flowId]){
                            pos =  ((char*)p_tx_srs_play_buffer[flowId]) + tx_srs_play_buffer_position[flowId];
                            ptr = psBbuIo->sFHSrsRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;

                            if(startupConfiguration.srsSymMask & (1 << sym_id) ){
                                if(ptr && pos){
                                    u32dptr = (uint32_t*)(ptr);
                                    memset(u32dptr,0 , pXranConf->nULRBs*N_SC_PER_PRB*4);
                                    rte_memcpy(u32dptr, pos, pXranConf->nULRBs*N_SC_PER_PRB*4);
                                } else {
                                    exit(-1);
                                    printf("ptr ==NULL\n");
                                }
                            }

                            tx_srs_play_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;

                            if(tx_srs_play_buffer_position[flowId] >= tx_srs_play_buffer_size[flowId])
                                tx_srs_play_buffer_position[flowId] = 0;
                        } else {
                            //printf("flowId %d\n", flowId);
                        }
                    }
                }
            }
        }
    }

    return 0;
}

void stop_xran(void)
{
    xran_status_t status = 0;
    SWXRANInterfaceTypeEnum eInterfaceType;

    free(gpXranLibConfig);
    gpXranLibConfig = NULL;

    status += xran_mm_destroy(xranHandle)*2;

    if(XRAN_STATUS_SUCCESS != status)
    {
        printf("Failed at  xran_mm_destroy, status %d\n",status);
        iAssert(status == XRAN_STATUS_SUCCESS);
    }
}

int get_xran_iq_content(void)
{
    BbuXranIoIfStruct *psBbuIo = xran_get_ctx();
    xran_status_t status;
    int32_t nSectorIndex[XRAN_MAX_SECTOR_NR];
    int32_t nSectorNum;
    int32_t cc_id, ant_id, sym_id, tti;
    int32_t flowId;

    uint8_t    frame_id    = 0;
    uint8_t    subframe_id = 0;
    uint8_t    slot_id     = 0;
    uint8_t    sym         = 0;

    void *ptr;
    uint32_t *u32dptr;
    uint16_t *u16dptr;
    uint8_t  *u8dptr;

    uint32_t xran_max_antenna_nr = RTE_MAX(startupConfiguration.numAxc, startupConfiguration.numUlAxc);
    uint32_t xran_max_ant_array_elm_nr = RTE_MAX(startupConfiguration.antElmTRx, xran_max_antenna_nr);

    char        *pos = NULL;

    for (nSectorNum = 0; nSectorNum < XRAN_MAX_SECTOR_NR; nSectorNum++)
    {
        nSectorIndex[nSectorNum] = nSectorNum;
    }
    nSectorNum = numCCPorts;
    printf ("get_xran_iq_content\n");

    /* Init Memory */
    for(cc_id = 0; cc_id <nSectorNum; cc_id++)
    {
        for(tti  = 0; tti  < XRAN_N_FE_BUF_LEN; tti++) {
            for(ant_id = 0; ant_id < xran_max_antenna_nr; ant_id++){
                int32_t idxElm = 0;
                struct xran_prb_map *pRbMap = NULL;
                struct xran_prb_elm *pRbElm = NULL;
                struct xran_section_desc *p_sec_desc = NULL;
                pRbMap = (struct xran_prb_map *) psBbuIo->sFrontHaulRxPrbMapBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers->pData;
                if(pRbMap == NULL)
                    exit(-1);

                if(startupConfiguration.appMode == APP_O_RU)
                    flowId = startupConfiguration.numAxc * cc_id + ant_id;
                else
                    flowId = startupConfiguration.numUlAxc * cc_id + ant_id;

                for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++) {
                    pRbElm = &pRbMap->prbMap[0];
                    if(pRbMap->nPrbElm == 1){
                        if(p_rx_log_buffer[flowId]) {
                            pos =  ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
                            ptr =  psBbuIo->sFrontHaulRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
                            if(ptr){
                                u32dptr = (uint32_t*)(ptr);
                                rte_memcpy(pos + pRbElm->nRBStart*N_SC_PER_PRB*4L , u32dptr, pRbElm->nRBSize*N_SC_PER_PRB*4L);
                            }else {
                                printf("[%d][%d][%d][%d]ptr ==NULL\n",tti,cc_id,ant_id, sym_id);
                            }
                        }
                    } else {
                        for(idxElm = 0; idxElm < pRbMap->nPrbElm; idxElm++ ) {
                            pRbElm = &pRbMap->prbMap[idxElm];
                            p_sec_desc = pRbElm->p_sec_desc[sym_id];
                            if(p_rx_log_buffer[flowId] && p_sec_desc){
                                if(sym_id >= pRbElm->nStartSymb && sym_id < pRbElm->nStartSymb + pRbElm->numSymb){
                                    pos =  ((char*)p_rx_log_buffer[flowId]) + rx_log_buffer_position[flowId];
                                    ptr = p_sec_desc->pData;
                                    if(ptr){
                                        int32_t payload_len = 0;
                                        u32dptr = (uint32_t*)(ptr);
                                        if (pRbElm->compMethod != XRAN_COMPMETHOD_NONE){
                                            struct xranlib_decompress_request  bfp_decom_req;
                                            struct xranlib_decompress_response bfp_decom_rsp;

                                            memset(&bfp_decom_req, 0, sizeof(struct xranlib_decompress_request));
                                            memset(&bfp_decom_rsp, 0, sizeof(struct xranlib_decompress_response));

                                            bfp_decom_req.data_in    = (int8_t *)u32dptr;
                                            bfp_decom_req.numRBs     = pRbElm->nRBSize;
                                            bfp_decom_req.len        = (3* pRbElm->iqWidth + 1)*pRbElm->nRBSize;
                                            bfp_decom_req.compMethod = pRbElm->compMethod;
                                            bfp_decom_req.iqWidth    = pRbElm->iqWidth;

                                            bfp_decom_rsp.data_out   = (int16_t *)(pos + pRbElm->nRBStart*N_SC_PER_PRB*4);
                                            bfp_decom_rsp.len        = 0;

                                            xranlib_decompress_avx512(&bfp_decom_req, &bfp_decom_rsp);
                                            payload_len = bfp_decom_rsp.len;

                                       } else {
                                            rte_memcpy(pos + pRbElm->nRBStart*N_SC_PER_PRB*4 , u32dptr, pRbElm->nRBSize*N_SC_PER_PRB*4);
                                       }
                                    }
                                }
                            }
                        }
                    }
                    rx_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;

                    if(rx_log_buffer_position[flowId] >= rx_log_buffer_size[flowId])
                        rx_log_buffer_position[flowId] = 0;
                }

                /* prach RX for O-DU only */
                if(startupConfiguration.appMode == APP_O_DU) {
                    flowId = startupConfiguration.numAxc * cc_id + ant_id;
                    for(sym_id = 0; sym_id < XRAN_NUM_OF_SYMBOL_PER_SLOT; sym_id++){
                        if(p_prach_log_buffer[flowId]){
                            /* (0-79 slots) 10ms of IQs */
                            pos =  ((char*)p_prach_log_buffer[flowId]) + prach_log_buffer_position[flowId];
                            ptr = psBbuIo->sFHPrachRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData; //8192 144
                            if(ptr){
                                u32dptr = (uint32_t*)(ptr);
                                rte_memcpy(pos, u32dptr, PRACH_PLAYBACK_BUFFER_BYTES);
                            }else
                                printf("ptr ==NULL\n");

                            prach_log_buffer_position[flowId] += PRACH_PLAYBACK_BUFFER_BYTES;

                            if(prach_log_buffer_position[flowId] >= prach_log_buffer_size[flowId])
                                prach_log_buffer_position[flowId] = 0;
                        } else {
                            //printf("flowId %d\n", flowId);
                        }
                    }
                }
            }

            /* SRS RX for O-DU only */
            if(startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs) {
                for(ant_id = 0; ant_id < xran_max_ant_array_elm_nr; ant_id++){
                    flowId = startupConfiguration.antElmTRx*cc_id + ant_id;
                    for(sym_id = 0; sym_id < XRAN_MAX_NUM_OF_SRS_SYMBOL_PER_SLOT; sym_id++){
                        if(p_srs_log_buffer[flowId]){
                            pos =  ((char*)p_srs_log_buffer[flowId]) + srs_log_buffer_position[flowId];
                            ptr = psBbuIo->sFHSrsRxBbuIoBufCtrl[tti][cc_id][ant_id].sBufferList.pBuffers[sym_id].pData;
                            if(ptr){
                                u32dptr = (uint32_t*)(ptr);
                                rte_memcpy(pos, u32dptr, pXranConf->nULRBs*N_SC_PER_PRB*4);
                            }else
                                printf("ptr ==NULL\n");

                            srs_log_buffer_position[flowId] += pXranConf->nULRBs*N_SC_PER_PRB*4;

                            if(srs_log_buffer_position[flowId] >= srs_log_buffer_size[flowId])
                                srs_log_buffer_position[flowId] = 0;
                        } else {
                            //printf("flowId %d\n", flowId);
                        }
                    }
                }
            }
        }
    }

    return 0;
}

void version_print(void)
{
    char            sysversion[100];
    char           *compilation_date = __DATE__;
    char           *compilation_time = __TIME__;

    uint32_t          nLen;

    snprintf(sysversion, 99, "Version: %s", VERSIONX);
    nLen = strlen(sysversion);

    printf("\n\n");
    printf("===========================================================================================================\n");
    printf("SAMPLE-APP VERSION\n");
    printf("===========================================================================================================\n");

    printf("%s\n", sysversion);
    printf("build-date: %s\n", compilation_date);
    printf("build-time: %s\n", compilation_time);
}

static void app_Help(void)
{
    char help_content[] =  \
            "sample application\n\n"\
            "Usage: sample-app config_file_o_du.dat -p 2  0000:21:02.0  0000:21:02.1 0000:21:0a.0  0000:21:0a.1\n\n"\
	            "supports the following parameters:\n\n"\
            "-p | --num_eth_pfs <number of ETH ports to connect to O-RU|O-DU>     1 - default sanity test\n"
            "-c | --cfgfile <name of cfg file>\n"\
            "-h | --help         print usage\n";

    printf("%s", help_content);
}

/**
 *******************************************************************************
 *
 * @fn    app_parse_args
 * @brief is used to parse incoming app args
 *
 * @param[i]  argc - app arg count
 * @param[i]  argv - array of args
 * @param[o]  params - app startup params filled basing on args parse
 * @return    number of parsed args
 *
 * @description
 *    The routine is parse input args and convert them into app startup params
 *
 * @references
 * MS-111070-SP
 *
 * @ingroup icc_service_unit_test
 *
 ******************************************************************************/
static int app_parse_args(int argc, char ** argv, struct sample_app_params* params)
{
    int c;
    int *pInt;
    int cnt = 0;

    struct option long_options[] = {
        {"cfgfile", required_argument, 0, 'c'},
        {"num_eth_pfs", required_argument, 0, 'p'},
        {"help", no_argument, 0, 'h'},
        {0, 0, 0, 0}
    };

    memset(params, 0, sizeof (*params));

    while (1) {
        //int this_option_optind = optind ? optind : 1;
        int option_index = 0;

        c = getopt_long(argc, argv, "c:p:h", long_options, &option_index);

        if (c == -1)
            break;

        cnt += 1;
        pInt = NULL;

        switch (c) {
            case 'p': // test Case selection
                pInt = &params->num_vfs;
                break;
            case 'c':
                params->cfg_file = optarg;
                break;
            case 'h':
                app_Help();
                exit(0);
        }

        if (pInt && optarg) {
            // get int arg
            if (optarg[0] == '0' && (optarg[1] == 'x' || optarg[1] == 'X')) {
                sscanf(optarg, "%x", (unsigned *) pInt);
            } else {
                *pInt = atoi(optarg);
            }
        }
    }
    return cnt;
}

int32_t app_init_set_eAxCId_conf(struct xran_eaxcid_config *p_eAxC_cfg, RuntimeConfig * p_s_cfg)
{
    int32_t shift;
    uint16_t mask;

    if(p_s_cfg->DU_Port_ID_bitwidth && p_s_cfg->BandSector_ID_bitwidth && p_s_cfg->CC_ID_bitwidth
        && p_s_cfg->RU_Port_ID_bitwidth &&
        (p_s_cfg->DU_Port_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth + p_s_cfg->CC_ID_bitwidth
                 + p_s_cfg->RU_Port_ID_bitwidth) == 16 /* eAxC ID subfields are 16 bits */
        ){ /* bit mask provided */

        mask = 0;
        p_eAxC_cfg->bit_ruPortId = 0;
        for (shift = 0; shift < p_s_cfg->RU_Port_ID_bitwidth; shift++){
            mask |= 1 << shift;
        }
        p_eAxC_cfg->mask_ruPortId = mask;

        p_eAxC_cfg->bit_ccId = p_s_cfg->RU_Port_ID_bitwidth;
        mask = 0;
        for (shift = p_s_cfg->RU_Port_ID_bitwidth; shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth; shift++){
            mask |= 1 << shift;
        }
        p_eAxC_cfg->mask_ccId = mask;


        p_eAxC_cfg->bit_bandSectorId = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth;
        mask = 0;
        for (shift = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth; shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth; shift++){
            mask |= 1 << shift;
        }
        p_eAxC_cfg->mask_bandSectorId = mask;

        p_eAxC_cfg->bit_cuPortId = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth;
        mask = 0;
        for (shift = p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth;
            shift < p_s_cfg->RU_Port_ID_bitwidth + p_s_cfg->CC_ID_bitwidth + p_s_cfg->BandSector_ID_bitwidth + p_s_cfg->DU_Port_ID_bitwidth; shift++){
            mask |= 1 << shift;
        }
        p_eAxC_cfg->mask_cuPortId = mask;


    } else { /* bit mask config is not provided */
        switch (p_s_cfg->xranCat){
            case XRAN_CATEGORY_A: {
                p_eAxC_cfg->mask_cuPortId      = 0xf000;
                p_eAxC_cfg->mask_bandSectorId  = 0x0f00;
                p_eAxC_cfg->mask_ccId          = 0x00f0;
                p_eAxC_cfg->mask_ruPortId      = 0x000f;
                p_eAxC_cfg->bit_cuPortId       = 12;
                p_eAxC_cfg->bit_bandSectorId   = 8;
                p_eAxC_cfg->bit_ccId           = 4;
                p_eAxC_cfg->bit_ruPortId       = 0;
                break;
            }
            case XRAN_CATEGORY_B: {
                p_eAxC_cfg->mask_cuPortId      = 0xf000;
                p_eAxC_cfg->mask_bandSectorId  = 0x0c00;
                p_eAxC_cfg->mask_ccId          = 0x0300;
                p_eAxC_cfg->mask_ruPortId      = 0x00ff; /* more than [0-127] eAxC */
                p_eAxC_cfg->bit_cuPortId       = 12;
                p_eAxC_cfg->bit_bandSectorId   = 10;
                p_eAxC_cfg->bit_ccId           = 8;
                p_eAxC_cfg->bit_ruPortId       = 0;
                break;
            }
            default:
                rte_panic("Incorrect Category\n");
        }
    }

    if(p_s_cfg->xranCat == XRAN_CATEGORY_A)
        p_s_cfg->numUlAxc = p_s_cfg->numAxc;

    printf("bit_cuPortId     %2d mask 0x%04x\n",p_eAxC_cfg->bit_cuPortId, p_eAxC_cfg->mask_cuPortId);
    printf("bit_bandSectorId %2d mask 0x%04x\n",p_eAxC_cfg->bit_bandSectorId, p_eAxC_cfg->mask_bandSectorId);
    printf("bit_ccId         %2d mask 0x%04x\n",p_eAxC_cfg->bit_ccId, p_eAxC_cfg->mask_ccId);
    printf("ruPortId         %2d mask 0x%04x\n",p_eAxC_cfg->bit_ruPortId, p_eAxC_cfg->mask_ruPortId);

    return 0;
}

int main(int argc, char *argv[])
{
    int i;
    int j, len;
    int  lcore_id = 0;
    char filename[256];
    char prefix_name[256];
    uint32_t nCenterFreq;
    int32_t xret = 0;
    struct stat st = {0};
    uint32_t filenameLength = strlen(argv[1]);
    enum xran_if_state xran_curr_if_state = XRAN_INIT;
    struct sample_app_params arg_params;


    uint64_t nTotalTime;
    uint64_t nUsedTime;
    uint32_t nCoreUsed;
    float nUsedPercent;

    app_parse_args(argc, argv, &arg_params);

    if( (arg_params.num_vfs % 2) != 0 || arg_params.num_vfs >= XRAN_VF_MAX){
        printf("warning: arg_params.num_vfs is not correct\n");
        exit(-1);
    }

    if (argc == 3 + arg_params.num_vfs){
        printf("Need at least two argument - the PCI address of the network port");
        exit(-1);
    }

    if (filenameLength >= 256)
    {
        printf("Config file name input is too long, exiting!\n");
        exit(-1);
    }

    version_print();

    //add for Klocworks
    printf("arg_params.cfg_file (%s)\n", arg_params.cfg_file);
    len = strlen(arg_params.cfg_file) + 1;
    if (len > (sizeof(filename) - 10))
        len = (sizeof(filename) - 10);
    strncpy(filename, arg_params.cfg_file, (sizeof(filename) - 10));
    filename[len] = '\0';

    if (xran_is_synchronized() != 0)
        printf("Machine is not synchronized using PTP!\n");
    else
        printf("Machine is synchronized using PTP!\n");

    memset(&startupConfiguration, 0, sizeof(RuntimeConfig));

    if (parseConfigFile(filename, (RuntimeConfig*)&startupConfiguration) != 0) {
        printf("Configuration file error.\n");
        return -1;
    }

    if(startupConfiguration.ant_file[0] == NULL){
        printf("it looks like test vector for antennas were not provided\n");
        exit(-1);
    }

    if (startupConfiguration.numCC > XRAN_MAX_SECTOR_NR) {
        printf("Number of cells %d exceeds max number supported %d!\n", startupConfiguration.numCC, XRAN_MAX_SECTOR_NR);
        startupConfiguration.numCC = XRAN_MAX_SECTOR_NR;

    }
    if (startupConfiguration.antElmTRx > XRAN_MAX_ANT_ARRAY_ELM_NR) {
        printf("Number of Antenna elements %d exceeds max number supported %d!\n", startupConfiguration.antElmTRx, XRAN_MAX_ANT_ARRAY_ELM_NR);
        startupConfiguration.antElmTRx = XRAN_MAX_ANT_ARRAY_ELM_NR;
    }

    numCCPorts = startupConfiguration.numCC;
    num_eAxc   = startupConfiguration.numAxc;

    printf("numCCPorts %d num_eAxc%d\n", numCCPorts, num_eAxc);

    if (startupConfiguration.mu_number <= 1){
        nFpgaToSW_FTH_RxBufferLen    = 13168; /* 273*12*4 + 64*/
        nFpgaToSW_PRACH_RxBufferLen  = 8192;
        nSW_ToFpga_FTH_TxBufferLen   = 13168 + /* 273*12*4 + 64* + ETH AND ORAN HDRs */
                        XRAN_MAX_SECTIONS_PER_SYM* (RTE_PKTMBUF_HEADROOM + sizeof(struct rte_ether_hdr) +
                        sizeof(struct xran_ecpri_hdr) +
                        sizeof(struct radio_app_common_hdr) +
                        sizeof(struct data_section_hdr));
    } else if (startupConfiguration.mu_number == 3){
        nFpgaToSW_FTH_RxBufferLen    = 3328;
        nFpgaToSW_PRACH_RxBufferLen  = 8192;
        nSW_ToFpga_FTH_TxBufferLen   = 3328 +
                        XRAN_MAX_SECTIONS_PER_SYM * (RTE_PKTMBUF_HEADROOM + sizeof(struct rte_ether_hdr) +
                        sizeof(struct xran_ecpri_hdr) +
                        sizeof(struct radio_app_common_hdr) +
                        sizeof(struct data_section_hdr));
    } else {
        printf("given numerology is not supported %d\n", startupConfiguration.mu_number);
        exit(-1);
    }
    printf("nSW_ToFpga_FTH_TxBufferLen %d\n", nSW_ToFpga_FTH_TxBufferLen);

    memset(&xranInit, 0, sizeof(struct xran_fh_init));

    if(startupConfiguration.appMode == APP_O_DU) {
        printf("set O-DU\n");
        xranInit.io_cfg.id = 0;/* O-DU */
        xranInit.io_cfg.core          = startupConfiguration.io_core;
        xranInit.io_cfg.system_core   = startupConfiguration.system_core;
        xranInit.io_cfg.pkt_proc_core = startupConfiguration.io_worker; /* do not start */
        xranInit.io_cfg.pkt_aux_core  = 0; /* do not start*/
        xranInit.io_cfg.timing_core   = startupConfiguration.io_core;
        xranInit.io_cfg.dpdkIoVaMode  = startupConfiguration.iova_mode;
    } else {
        printf("set O-RU\n");
        xranInit.io_cfg.id = 1; /* O-RU*/
        xranInit.io_cfg.core          = startupConfiguration.io_core;
        xranInit.io_cfg.system_core   = startupConfiguration.system_core;
        xranInit.io_cfg.pkt_proc_core = startupConfiguration.io_worker; /* do not start */
        xranInit.io_cfg.pkt_aux_core  = 0; /* do not start */
        xranInit.io_cfg.timing_core   = startupConfiguration.io_core;
        xranInit.io_cfg.dpdkIoVaMode  = startupConfiguration.iova_mode;
    }

    xranInit.io_cfg.io_sleep   = startupConfiguration.io_sleep;
    xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;

    app_init_set_eAxCId_conf(&xranInit.eAxCId_conf, &startupConfiguration);

    printf("arg_params.num_vfs %d\n", arg_params.num_vfs);
    for(i = 0; i < arg_params.num_vfs/2; i++){
        xranInit.io_cfg.dpdk_dev[XRAN_UP_VF+2*i]       = argv[5+2*i];
        printf("VF[%d] %s\n",XRAN_UP_VF+2*i,  xranInit.io_cfg.dpdk_dev[XRAN_UP_VF+2*i]);
        xranInit.io_cfg.dpdk_dev[XRAN_UP_VF+2*i+1]     = argv[5+2*i+1];
        printf("VF[%d] %s\n",XRAN_UP_VF+2*i+1,  xranInit.io_cfg.dpdk_dev[XRAN_UP_VF+2*i+1]);
    }

    xranInit.io_cfg.num_vfs    = arg_params.num_vfs;
    xranInit.mtu                = startupConfiguration.mtu;
    xranInit.p_o_du_addr = (int8_t *)startupConfiguration.o_du_addr;
    xranInit.p_o_ru_addr = (int8_t *)startupConfiguration.o_ru_addr;

    sprintf(prefix_name, "wls_%d",startupConfiguration.instance_id);
    xranInit.filePrefix  = prefix_name;

    xranInit.totalBfWeights = startupConfiguration.totalBfWeights;

    xranInit.Tadv_cp_dl     = startupConfiguration.Tadv_cp_dl;
    xranInit.T2a_min_cp_dl  = startupConfiguration.T2a_min_cp_dl;
    xranInit.T2a_max_cp_dl  = startupConfiguration.T2a_max_cp_dl;
    xranInit.T2a_min_cp_ul  = startupConfiguration.T2a_min_cp_ul;
    xranInit.T2a_max_cp_ul  = startupConfiguration.T2a_max_cp_ul;
    xranInit.T2a_min_up     = startupConfiguration.T2a_min_up;
    xranInit.T2a_max_up     = startupConfiguration.T2a_max_up;
    xranInit.Ta3_min        = startupConfiguration.Ta3_min;
    xranInit.Ta3_max        = startupConfiguration.Ta3_max;
    xranInit.T1a_min_cp_dl  = startupConfiguration.T1a_min_cp_dl;
    xranInit.T1a_max_cp_dl  = startupConfiguration.T1a_max_cp_dl;
    xranInit.T1a_min_cp_ul  = startupConfiguration.T1a_min_cp_ul;
    xranInit.T1a_max_cp_ul  = startupConfiguration.T1a_max_cp_ul;
    xranInit.T1a_min_up     = startupConfiguration.T1a_min_up;
    xranInit.T1a_max_up     = startupConfiguration.T1a_max_up;
    xranInit.Ta4_min        = startupConfiguration.Ta4_min;
    xranInit.Ta4_max        = startupConfiguration.Ta4_max;

    xranInit.enableCP       = startupConfiguration.enableCP;
    xranInit.prachEnable    = startupConfiguration.enablePrach;
    xranInit.srsEnable      = startupConfiguration.enableSrs;
    xranInit.debugStop      = startupConfiguration.debugStop;
    xranInit.debugStopCount = startupConfiguration.debugStopCount;
    xranInit.DynamicSectionEna = startupConfiguration.DynamicSectionEna;
    xranInit.io_cfg.bbdev_mode = XRAN_BBDEV_NOT_USED;
    xranInit.GPS_Alpha         = startupConfiguration.GPS_Alpha;
    xranInit.GPS_Beta          = startupConfiguration.GPS_Beta;

    xranInit.cp_vlan_tag    = startupConfiguration.cp_vlan_tag;
    xranInit.up_vlan_tag    = startupConfiguration.up_vlan_tag;

    printf("IQ files size is %d slots\n", startupConfiguration.numSlots);

    iq_playback_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
                                 app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
                                 *4L);

    iq_playback_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
                                 app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
                                 *4L);


    /* 10 * [14*32*273*2*2] = 4892160 bytes */
    iq_bfw_buffer_size_dl = (startupConfiguration.numSlots * N_SYM_PER_SLOT *  startupConfiguration.antElmTRx *
                                 app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA)
                                 *4L);

    /* 10 * [14*32*273*2*2] = 4892160 bytes */
    iq_bfw_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT *
                                 app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
                                 *4L);

    /* 10 * [1*273*2*2] = 349440 bytes */
    iq_srs_buffer_size_ul = (startupConfiguration.numSlots * N_SYM_PER_SLOT * N_SC_PER_PRB *
                                 app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA)
                                 *4L);

    for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
        p_tx_play_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_dl);
        tx_play_buffer_size[i] = (int32_t)iq_playback_buffer_size_dl;

        if (p_tx_play_buffer[i] == NULL)
            exit(-1);

        tx_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ant_file[i],
                            "DL IFFT IN IQ Samples in binary format",
                            (uint8_t*) p_tx_play_buffer[i],
                            tx_play_buffer_size[i],
                            1);
        tx_play_buffer_position[i] = 0;
    }

    if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){
        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

            p_tx_dl_bfw_buffer[i]    = (int16_t*)malloc(iq_bfw_buffer_size_dl);
            tx_dl_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_dl;

            if (p_tx_dl_bfw_buffer[i] == NULL)
                exit(-1);

            tx_dl_bfw_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.dl_bfw_file[i],
                                "DL BF weights IQ Samples in binary format",
                                (uint8_t*) p_tx_dl_bfw_buffer[i],
                                tx_dl_bfw_buffer_size[i],
                                1);
            tx_dl_bfw_buffer_position[i] = 0;
        }
    }

    if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){

        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
            p_tx_ul_bfw_buffer[i]    = (int16_t*)malloc(iq_bfw_buffer_size_ul);
            tx_ul_bfw_buffer_size[i] = (int32_t)iq_bfw_buffer_size_ul;

            if (p_tx_ul_bfw_buffer[i] == NULL)
                exit(-1);

            tx_ul_bfw_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ul_bfw_file[i],
                                "UL BF weights IQ Samples in binary format",
                                (uint8_t*) p_tx_ul_bfw_buffer[i],
                                tx_ul_bfw_buffer_size[i],
                                1);
            tx_ul_bfw_buffer_position[i] = 0;
        }
    }

    if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
         for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
             p_tx_prach_play_buffer[i]    = (int16_t*)malloc(PRACH_PLAYBACK_BUFFER_BYTES);
             tx_prach_play_buffer_size[i] = (int32_t)PRACH_PLAYBACK_BUFFER_BYTES;

             if (p_tx_prach_play_buffer[i] == NULL)
                 exit(-1);

             memset(p_tx_prach_play_buffer[i], 0, PRACH_PLAYBACK_BUFFER_BYTES);

             tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.prach_file[i],
                                 "PRACH IQ Samples in binary format",
                                 (uint8_t*) p_tx_prach_play_buffer[i],
                                 tx_prach_play_buffer_size[i],
                                 1);
             tx_prach_play_buffer_position[i] = 0;
         }
    }

    if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){
         for(i = 0;
             i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
             i++) {

             p_tx_srs_play_buffer[i]    = (int16_t*)malloc(iq_srs_buffer_size_ul);
             tx_srs_play_buffer_size[i] = (int32_t)iq_srs_buffer_size_ul;

             if (p_tx_srs_play_buffer[i] == NULL)
                 exit(-1);

             memset(p_tx_srs_play_buffer[i], 0, iq_srs_buffer_size_ul);
             tx_prach_play_buffer_size[i] = sys_load_file_to_buff(startupConfiguration.ul_srs_file[i],
                                 "SRS IQ Samples in binary format",
                                 (uint8_t*) p_tx_srs_play_buffer[i],
                                 tx_srs_play_buffer_size[i],
                                 1);

             tx_srs_play_buffer_position[i] = 0;
         }
    }

    /* log of ul */
    for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        p_rx_log_buffer[i]    = (int16_t*)malloc(iq_playback_buffer_size_ul);
        rx_log_buffer_size[i] = (int32_t)iq_playback_buffer_size_ul;

        if (p_rx_log_buffer[i] == NULL)
            exit(-1);

        rx_log_buffer_position[i] = 0;

        memset(p_rx_log_buffer[i], 0, rx_log_buffer_size[i]);
    }

    /* log of prach */
    for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        p_prach_log_buffer[i]    = (int16_t*)malloc(startupConfiguration.numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES);
        prach_log_buffer_size[i] = (int32_t)startupConfiguration.numSlots*XRAN_NUM_OF_SYMBOL_PER_SLOT*PRACH_PLAYBACK_BUFFER_BYTES;

        if (p_prach_log_buffer[i] == NULL)
            exit(-1);

        memset(p_prach_log_buffer[i], 0, prach_log_buffer_size[i]);
        prach_log_buffer_position[i] = 0;
    }

    /* log of SRS */
    if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){
        for(i = 0;
            i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
            i++) {

             p_srs_log_buffer[i]    = (int16_t*)malloc(iq_srs_buffer_size_ul);
             srs_log_buffer_size[i] = (int32_t)iq_srs_buffer_size_ul;

             if (p_srs_log_buffer[i] == NULL)
                 exit(-1);

             memset(p_srs_log_buffer[i], 0, iq_srs_buffer_size_ul);
             srs_log_buffer_position[i] = 0;
        }
    }

    if (stat("./logs", &st) == -1) {
        mkdir("./logs", 0777);
    }

    for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        sprintf(filename, "./logs/%s-play_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
        sys_save_buf_to_file_txt(filename,
                            "DL IFFT IN IQ Samples in human readable format",
                            (uint8_t*) p_tx_play_buffer[i],
                            tx_play_buffer_size[i],
                            1);

        sprintf(filename, "./logs/%s-play_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
        sys_save_buf_to_file(filename,
                            "DL IFFT IN IQ Samples in binary format",
                            (uint8_t*) p_tx_play_buffer[i],
                            tx_play_buffer_size[i]/sizeof(short),
                            sizeof(short));


        if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){
            sprintf(filename, "./logs/%s-dl_bfw_ue%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                                "DL Beamformig weights IQ Samples in human readable format",
                                (uint8_t*) p_tx_dl_bfw_buffer[i],
                                tx_dl_bfw_buffer_size[i],
                                1);

            sprintf(filename, "./logs/%s-dl_bfw_ue%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "DL Beamformig weightsIQ Samples in binary format",
                                (uint8_t*) p_tx_dl_bfw_buffer[i],
                                tx_dl_bfw_buffer_size[i]/sizeof(short),
                                sizeof(short));


            sprintf(filename, "./logs/%s-ul_bfw_ue%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                                "UL Beamformig weights IQ Samples in human readable format",
                                (uint8_t*) p_tx_ul_bfw_buffer[i],
                                tx_ul_bfw_buffer_size[i],
                                1);

            sprintf(filename, "./logs/%s-ul_bfw_ue%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "UL Beamformig weightsIQ Samples in binary format",
                                (uint8_t*) p_tx_ul_bfw_buffer[i],
                                tx_ul_bfw_buffer_size[i]/sizeof(short),
                                sizeof(short));

        }

        if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
            sprintf(filename, "./logs/%s-play_prach_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                                "PRACH IQ Samples in human readable format",
                                (uint8_t*) p_tx_prach_play_buffer[i],
                                tx_prach_play_buffer_size[i],
                                1);

            sprintf(filename, "./logs/%s-play_prach_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "PRACH IQ Samples in binary format",
                                (uint8_t*) p_tx_prach_play_buffer[i],
                                tx_prach_play_buffer_size[i]/sizeof(short),
                                sizeof(short));
        }
    }

    if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs && startupConfiguration.xranCat == XRAN_CATEGORY_B){
       for(i = 0;
           i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
           i++) {


            sprintf(filename, "./logs/%s-play_srs_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                            "SRS IQ Samples in human readable format",
                            (uint8_t*) p_tx_srs_play_buffer[i],
                            tx_srs_play_buffer_size[i],
                            1);

            sprintf(filename, "./logs/%s-play_srs_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "SRS IQ Samples in binary format",
                                (uint8_t*) p_tx_srs_play_buffer[i],
                                tx_srs_play_buffer_size[i]/sizeof(short),
                                sizeof(short));
        }
    }

    if (startupConfiguration.iqswap == 1){
        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
            printf("TX: Swap I and Q to match RU format: [%d]\n",i);
            {
                /* swap I and Q */
                int32_t j;
                signed short *ptr = (signed short *)  p_tx_play_buffer[i];
                signed short temp;

                for (j = 0; j < (int32_t)(tx_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
                   temp    = ptr[j];
                   ptr[j]  = ptr[j + 1];
                   ptr[j + 1] = temp;
                }
            }
            if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){
                printf("DL BFW: Swap I and Q to match RU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_tx_dl_bfw_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(tx_dl_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
                printf("UL BFW: Swap I and Q to match RU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_tx_ul_bfw_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(tx_ul_bfw_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
            }
        }

        if (startupConfiguration.appMode == APP_O_RU){
            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
                printf("PRACH: Swap I and Q to match RU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_tx_prach_play_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(tx_prach_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
            }
        }

        if (startupConfiguration.appMode == APP_O_RU){
            for(i = 0;
               i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
               i++) {
                 printf("SRS: Swap I and Q to match RU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_tx_srs_play_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(tx_srs_play_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
            }
        }
    }

#if 0
    for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        sprintf(filename, "./logs/swap_IQ_play_ant%d.txt", i);
        sys_save_buf_to_file_txt(filename,
                            "DL IFFT IN IQ Samples in human readable format",
                            (uint8_t*) p_tx_play_buffer[i],
                            tx_play_buffer_size[i],
                            1);
    }
#endif
    if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0){
        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
            printf("TX: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
            for (j = 0; j < tx_play_buffer_size[i]/sizeof(short); j++){
                p_tx_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_play_buffer[i][j]);
            }

            if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.xranCat == XRAN_CATEGORY_B){
                printf("DL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
                for (j = 0; j < tx_dl_bfw_buffer_size[i]/sizeof(short); j++){
                    p_tx_dl_bfw_buffer[i][j]  = rte_cpu_to_be_16(p_tx_dl_bfw_buffer[i][j]);
                }
                printf("UL BFW: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
                for (j = 0; j < tx_ul_bfw_buffer_size[i]/sizeof(short); j++){
                    p_tx_ul_bfw_buffer[i][j]  = rte_cpu_to_be_16(p_tx_ul_bfw_buffer[i][j]);
                }
            }
        }

        if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enablePrach){
            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
                printf("PRACH: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
                for (j = 0; j < tx_prach_play_buffer_size[i]/sizeof(short); j++){
                    p_tx_prach_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_prach_play_buffer[i][j]);
                }
            }
        }

        if (startupConfiguration.appMode == APP_O_RU && startupConfiguration.enableSrs){
               for(i = 0;
               i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
               i++)  {
                printf("SRS: Convert S16 I and S16 Q to network byte order for XRAN Ant: [%d]\n",i);
                for (j = 0; j < tx_srs_play_buffer_size[i]/sizeof(short); j++){
                    p_tx_srs_play_buffer[i][j]  = rte_cpu_to_be_16(p_tx_srs_play_buffer[i][j]);
                }
            }
        }

    }

#if 0
    for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        sprintf(filename, "./logs/swap_be_play_ant%d.txt", i);
        sys_save_buf_to_file_txt(filename,
                            "DL IFFT IN IQ Samples in human readable format",
                            (uint8_t*) p_tx_play_buffer[i],
                            tx_play_buffer_size[i],
                            1);
    }
#endif

    memset(&xranConf, 0, sizeof(struct xran_fh_config));
    pXranConf = &xranConf;

    pXranConf->nDLRBs = app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nDLBandwidth, startupConfiguration.nDLAbsFrePointA);
    pXranConf->nULRBs = app_xran_get_num_rbs(startupConfiguration.xranTech, startupConfiguration.mu_number, startupConfiguration.nULBandwidth, startupConfiguration.nULAbsFrePointA);

    if(startupConfiguration.DynamicSectionEna == 0){
        struct xran_prb_map* pRbMap;

        pRbMap = &startupConfiguration.PrbMapDl;

        pRbMap->dir = XRAN_DIR_DL;
        pRbMap->xran_port = 0;
        pRbMap->band_id = 0;
        pRbMap->cc_id = 0;
        pRbMap->ru_port_id = 0;
        pRbMap->tti_id = 0;
        pRbMap->start_sym_id = 0;
        pRbMap->nPrbElm = 1;
        pRbMap->prbMap[0].nStartSymb = 0;
        pRbMap->prbMap[0].numSymb = 14;
        pRbMap->prbMap[0].nRBStart = 0;
        pRbMap->prbMap[0].nRBSize = pXranConf->nDLRBs;
        pRbMap->prbMap[0].nBeamIndex = 0;
        pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
        pRbMap->prbMap[0].iqWidth    = 16;

        pRbMap = &startupConfiguration.PrbMapUl;
        pRbMap->dir = XRAN_DIR_UL;
        pRbMap->xran_port = 0;
        pRbMap->band_id = 0;
        pRbMap->cc_id = 0;
        pRbMap->ru_port_id = 0;
        pRbMap->tti_id = 0;
        pRbMap->start_sym_id = 0;
        pRbMap->nPrbElm = 1;
        pRbMap->prbMap[0].nStartSymb = 0;
        pRbMap->prbMap[0].numSymb = 14;
        pRbMap->prbMap[0].nRBStart = 0;
        pRbMap->prbMap[0].nRBSize = pXranConf->nULRBs;
        pRbMap->prbMap[0].nBeamIndex = 0;
        pRbMap->prbMap[0].compMethod = XRAN_COMPMETHOD_NONE;
        pRbMap->prbMap[0].iqWidth    = 16;
    } else {
        struct xran_prb_map* pRbMap;
        pRbMap = &startupConfiguration.PrbMapDl;

        pRbMap->dir = XRAN_DIR_DL;
        pRbMap->xran_port = 0;
        pRbMap->band_id = 0;
        pRbMap->cc_id = 0;
        pRbMap->ru_port_id = 0;
        pRbMap->tti_id = 0;
        pRbMap->start_sym_id = 0;

        pRbMap = &startupConfiguration.PrbMapUl;
        pRbMap->dir = XRAN_DIR_UL;
        pRbMap->xran_port = 0;
        pRbMap->band_id = 0;
        pRbMap->cc_id = 0;
        pRbMap->ru_port_id = 0;
        pRbMap->tti_id = 0;
        pRbMap->start_sym_id = 0;
    }

    timer_set_tsc_freq_from_clock();
    xret =  xran_init(argc, argv, &xranInit, argv[0], &xranHandle);
    if(xret != XRAN_STATUS_SUCCESS){
        printf("xran_init failed %d\n", xret);
        exit(-1);
    }

    if(xranHandle == NULL)
        exit(1);


    pXranConf->sector_id                        = 0;
    pXranConf->nCC                              = numCCPorts;
    pXranConf->neAxc                            = num_eAxc;
    pXranConf->neAxcUl                          = startupConfiguration.numUlAxc;
    pXranConf->nAntElmTRx                       = startupConfiguration.antElmTRx;

    pXranConf->frame_conf.nFrameDuplexType      = startupConfiguration.nFrameDuplexType;
    pXranConf->frame_conf.nNumerology           = startupConfiguration.mu_number;
    pXranConf->frame_conf.nTddPeriod            = startupConfiguration.nTddPeriod;

    for (i = 0; i < startupConfiguration.nTddPeriod; i++){
        pXranConf->frame_conf.sSlotConfig[i] = startupConfiguration.sSlotConfig[i];
    }

    pXranConf->prach_conf.nPrachSubcSpacing     = startupConfiguration.mu_number;
    pXranConf->prach_conf.nPrachFreqStart       = 0;
    pXranConf->prach_conf.nPrachFilterIdx       = XRAN_FILTERINDEX_PRACH_ABC;
    pXranConf->prach_conf.nPrachConfIdx         = startupConfiguration.prachConfigIndex;
    pXranConf->prach_conf.nPrachFreqOffset      = -792;

    pXranConf->srs_conf.symbMask                = startupConfiguration.srsSymMask;
    pXranConf->srs_conf.eAxC_offset             = 2 * startupConfiguration.numAxc; /* PUSCH, PRACH, SRS */

    pXranConf->ru_conf.xranTech                 = startupConfiguration.xranTech;
    pXranConf->ru_conf.xranCompHdrType          = startupConfiguration.CompHdrType;
    pXranConf->ru_conf.xranCat                  = startupConfiguration.xranCat;
    pXranConf->ru_conf.iqWidth                  = startupConfiguration.PrbMapDl.prbMap[0].iqWidth;

    if (startupConfiguration.compression == 0)
        pXranConf->ru_conf.compMeth                 = XRAN_COMPMETHOD_NONE;
    else
        pXranConf->ru_conf.compMeth                 = XRAN_COMPMETHOD_BLKFLOAT;

    pXranConf->ru_conf.fftSize                  = 0;
    while (startupConfiguration.nULFftSize >>= 1)
        ++pXranConf->ru_conf.fftSize;

    pXranConf->ru_conf.byteOrder = (startupConfiguration.nebyteorderswap == 1) ? XRAN_NE_BE_BYTE_ORDER : XRAN_CPU_LE_BYTE_ORDER  ;
    pXranConf->ru_conf.iqOrder   = (startupConfiguration.iqswap == 1) ? XRAN_Q_I_ORDER : XRAN_I_Q_ORDER;

    printf("FFT Order %d\n", pXranConf->ru_conf.fftSize);

    nCenterFreq = startupConfiguration.nDLAbsFrePointA + (((pXranConf->nDLRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
    pXranConf->nDLCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
    printf("DL center freq %d DL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nDLCenterFreqARFCN);

    nCenterFreq = startupConfiguration.nULAbsFrePointA + (((pXranConf->nULRBs * N_SC_PER_PRB) / 2) * app_xran_get_scs(startupConfiguration.mu_number));
    pXranConf->nULCenterFreqARFCN = app_xran_cal_nrarfcn(nCenterFreq);
    printf("UL center freq %d UL NR-ARFCN  %d\n", nCenterFreq, pXranConf->nULCenterFreqARFCN);

    pXranConf->bbdev_dec = NULL;
    pXranConf->bbdev_enc = NULL;

    pXranConf->log_level = 1;

    if(startupConfiguration.maxFrameId)
        pXranConf->ru_conf.xran_max_frame = startupConfiguration.maxFrameId;

    if(init_xran() != 0)
        exit(-1);

    xran_reg_physide_cb(xranHandle, physide_dl_tti_call_back, NULL, 10, XRAN_CB_TTI);
    xran_reg_physide_cb(xranHandle, physide_ul_half_slot_call_back, NULL, 10, XRAN_CB_HALF_SLOT_RX);
    xran_reg_physide_cb(xranHandle, physide_ul_full_slot_call_back, NULL, 10, XRAN_CB_FULL_SLOT_RX);

    init_xran_iq_content();

    xret = xran_open(xranHandle, pXranConf);

    if(xret != XRAN_STATUS_SUCCESS){
        printf("xran_open failed %d\n", xret);
        exit(-1);
    }

    sprintf(filename, "mlog-%s", startupConfiguration.appMode == 0 ? "o-du" : "o-ru");

    /* MLogOpen(0, 32, 0, 0xFFFFFFFF, filename);*/

    MLogOpen(256, 3, 20000, 0, filename);
    MLogSetMask(0);

    puts("----------------------------------------");
    printf("MLog Info: virt=0x%016lx size=%d\n", MLogGetFileLocation(), MLogGetFileSize());
    puts("----------------------------------------");


    uint64_t nActiveCoreMask[MAX_BBU_POOL_CORE_MASK] = {0};
    nActiveCoreMask[0] = (1 << xranInit.io_cfg.timing_core | xranInit.io_cfg.pkt_proc_core);

    MLogAddTestCase(nActiveCoreMask, startupConfiguration.numCC);

    fcntl(0, F_SETFL, fcntl(0, F_GETFL) | O_NONBLOCK);

    state = APP_RUNNING;
    printf("Start XRAN traffic\n");
    xran_start(xranHandle);
    sleep(3);
    print_menu();
    for (;;) {
        struct xran_common_counters x_counters;
        char input[10];
        sleep(1);
        xran_curr_if_state = xran_get_if_state();
        if(xran_get_common_counters(xranHandle, &x_counters) == XRAN_STATUS_SUCCESS) {

            xran_get_time_stats(&nTotalTime, &nUsedTime, &nCoreUsed, 1);
            nUsedPercent = ((float)nUsedTime * 100.0) / (float)nTotalTime;

            printf("[%s][rx %7ld pps %7ld kbps %7ld][tx %7ld pps %7ld kbps %7ld] [on_time %ld early %ld late %ld corrupt %ld pkt_dupl %ld Total %ld] IO Util: %5.2f %%\n",
                   ((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),
                   x_counters.rx_counter,
                   x_counters.rx_counter-old_rx_counter,
                   x_counters.rx_bytes_per_sec*8/1000L,
                   x_counters.tx_counter,
                   x_counters.tx_counter-old_tx_counter,
                   x_counters.tx_bytes_per_sec*8/1000L,
                   x_counters.Rx_on_time,
                   x_counters.Rx_early,
                   x_counters.Rx_late,
                   x_counters.Rx_corrupt,
                   x_counters.Rx_pkt_dupl,
                   x_counters.Total_msgs_rcvd,
                   nUsedPercent);

            if(x_counters.rx_counter > old_rx_counter)
                old_rx_counter = x_counters.rx_counter;
            if(x_counters.tx_counter > old_tx_counter)
                old_tx_counter = x_counters.tx_counter;

            if(x_counters.rx_counter > 0 && x_counters.tx_counter > 0)
                MLogSetMask(0xFFFFFFFF);
        } else {
            printf("error xran_get_common_counters\n");
        }

        if (xran_curr_if_state == XRAN_STOPPED){
            break;
        }
        if (NULL == fgets(input, 10, stdin)) {
            continue;
        }

        const int sel_opt = atoi(input);
        switch (sel_opt) {
            case 1:
                xran_start(xranHandle);
                printf("Start XRAN traffic\n");
                break;
            case 2:
                break;
            case 3:
                xran_stop(xranHandle);
                printf("Stop XRAN traffic\n");
                state = APP_STOPPED;
                break;
            default:
                puts("Wrong option passed!");
                break;
        }
        if (APP_STOPPED == state)
            break;
    }

    get_xran_iq_content();

    puts("Closing l1 app... Ending all threads...");
    xran_close(xranHandle);
    MLogPrint(NULL);

    stop_xran();
    puts("Dump IQs...");

    if (startupConfiguration.iqswap == 1){
        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
            printf("RX: Swap I and Q to match CPU format: [%d]\n",i);
            {
                /* swap I and Q */
                int32_t j;
                signed short *ptr = (signed short *)  p_rx_log_buffer[i];
                signed short temp;

                for (j = 0; j < (int32_t)(rx_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
                   temp    = ptr[j];
                   ptr[j]  = ptr[j + 1];
                   ptr[j + 1] = temp;
                }
            }
        }

        if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){
            for(i = 0;
            i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
            i++)  {
                printf("SRS: Swap I and Q to match CPU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_srs_log_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(srs_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
            }
        }
    }

    if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0) {

        for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
            printf("RX: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
            for (j = 0; j < rx_log_buffer_size[i]/sizeof(short); j++){
                p_rx_log_buffer[i][j]  = rte_be_to_cpu_16(p_rx_log_buffer[i][j]);
            }
        }

        if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){
            for(i = 0;
            i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
            i++)  {
                printf("SRS: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
                for (j = 0; j < srs_log_buffer_size[i]/sizeof(short); j++){
                    p_srs_log_buffer[i][j]  = rte_be_to_cpu_16(p_srs_log_buffer[i][j]);
                }
            }
        }
    }

    for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

        sprintf(filename, "./logs/%s-rx_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
        sys_save_buf_to_file_txt(filename,
                            "UL FFT OUT IQ Samples in human readable format",
                            (uint8_t*) p_rx_log_buffer[i],
                            rx_log_buffer_size[i],
                            1);

        sprintf(filename, "./logs/%s-rx_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
        sys_save_buf_to_file(filename,
                            "UL FFT OUT IQ Samples in binary format",
                            (uint8_t*) p_rx_log_buffer[i],
                            rx_log_buffer_size[i]/sizeof(short),
                            sizeof(short));
    }

    if (startupConfiguration.appMode == APP_O_DU && startupConfiguration.enableSrs){
        for(i = 0;
        i < MAX_ANT_CARRIER_SUPPORTED_CAT_B && i < (uint32_t)(numCCPorts * startupConfiguration.antElmTRx);
        i++) {
            sprintf(filename, "./logs/%s-srs_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                                "SRS UL FFT OUT IQ Samples in human readable format",
                                (uint8_t*) p_srs_log_buffer[i],
                                srs_log_buffer_size[i],
                                1);

            sprintf(filename, "./logs/%s-srs_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "SRS UL FFT OUT IQ Samples in binary format",
                                (uint8_t*) p_srs_log_buffer[i],
                                srs_log_buffer_size[i]/sizeof(short),
                                sizeof(short));
        }
    }

    if (startupConfiguration.appMode == APP_O_DU &&  startupConfiguration.enablePrach){
        if (startupConfiguration.iqswap == 1){
            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
                printf("PRACH: Swap I and Q to match CPU format: [%d]\n",i);
                {
                    /* swap I and Q */
                    int32_t j;
                    signed short *ptr = (signed short *)  p_prach_log_buffer[i];
                    signed short temp;

                    for (j = 0; j < (int32_t)(prach_log_buffer_size[i]/sizeof(short)) ; j = j + 2){
                       temp    = ptr[j];
                       ptr[j]  = ptr[j + 1];
                       ptr[j + 1] = temp;
                    }
                }
            }
        }


        if (startupConfiguration.nebyteorderswap == 1 && startupConfiguration.compression == 0){
            for(i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {
                printf("PRACH: Convert S16 I and S16 Q to cpu byte order from XRAN Ant: [%d]\n",i);
                for (j = 0; j < prach_log_buffer_size[i]/sizeof(short); j++){
                    p_prach_log_buffer[i][j]  = rte_be_to_cpu_16(p_prach_log_buffer[i][j]);
                }
            }
        }


        for (i = 0; i < MAX_ANT_CARRIER_SUPPORTED && i < (uint32_t)(numCCPorts * num_eAxc); i++) {

            sprintf(filename, "./logs/%s-prach_log_ant%d.txt",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"),  i);
            sys_save_buf_to_file_txt(filename,
                                "PRACH FFT OUT IQ Samples in human readable format",
                                (uint8_t*) p_prach_log_buffer[i],
                                prach_log_buffer_size[i],
                                1);

            sprintf(filename, "./logs/%s-prach_log_ant%d.bin",((startupConfiguration.appMode == APP_O_DU) ? "o-du" : "o-ru"), i);
            sys_save_buf_to_file(filename,
                                "PRACH FFT OUT IQ Samples in binary format",
                                (uint8_t*) p_prach_log_buffer[i],
                                prach_log_buffer_size[i]/sizeof(short),
                                sizeof(short));
        }
    }

    return 0;
}
